package com.zd.bms.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.zd.bms.bean.vo.req.OrderDetailListReqVo;
import com.zd.bms.bean.vo.req.OrderListReqVo;
import com.zd.bms.bean.vo.resp.DetailQrCodeVo;
import com.zd.bms.service.ITicketOrderDetailService;
import com.zd.common.bean.model.BmsUser;
import com.zd.common.bean.model.ScenicSpot;
import com.zd.common.bean.model.ShortQrcode;
import com.zd.common.bean.model.TicketInfo;
import com.zd.common.bean.model.TicketOrder;
import com.zd.common.bean.model.TicketOrderDetail;
import com.zd.common.common.enums.PrintStatusEnum;
import com.zd.common.common.enums.TicketVerifyTypeEnum;
import com.zd.common.common.enums.UseTicketsStatusEnum;
import com.zd.common.common.utils.LogUtils;
import com.zd.common.common.utils.QrCodeCreateUtil;
import com.zd.common.common.utils.StringUtils;
import com.zd.common.dao.ScenicSpotDao;
import com.zd.common.dao.ShortQrcodeDao;
import com.zd.common.dao.TicketInfoDao;
import com.zd.common.dao.TicketOrderDetailDao;
import com.zd.common.dao.common.BaseDao;
import com.zd.common.dao.common.FindRequestEntity;
import com.zd.common.dao.common.OrderEnum;
import com.zd.common.dao.common.Page;
import com.zd.common.dao.common.WhereEnum;
import com.zd.common.service.impl.BaseServiceImpl;

@Service
public class TicketOrderDetailServiceImpl extends BaseServiceImpl<TicketOrderDetail>
		implements ITicketOrderDetailService {

	@Autowired
	private TicketOrderDetailDao ticketOrderDetailDao;

	@Autowired
	private TicketInfoDao ticketInfoDao;
	
	@Autowired
	private ScenicSpotDao scenicSpotDao;
	
	@Autowired
	private ShortQrcodeDao shortQrcodeDao;

	@Override
	public BaseDao<TicketOrderDetail> getBaseDao() {
		// TODO Auto-generated method stub
		return ticketOrderDetailDao;
	}

	@Override
	public Page<TicketOrderDetail> pageTicketOrderDetail(OrderDetailListReqVo req) throws Exception {
		FindRequestEntity findReq = new FindRequestEntity();
		if (!StringUtils.isBank(req.getStartTime())) {
			findReq.addWhere("create_time", WhereEnum.GE, req.getStartTime());
		}
		if (!StringUtils.isBank(req.getEndTime())) {
			findReq.addWhere("create_time", WhereEnum.LE, req.getEndTime());
		}
		if (!StringUtils.isBank(req.getCheckCode())) {
			findReq.addWhere("check_code", WhereEnum.EQ, req.getCheckCode());
		}
		if (req.getScenicSpotId() != null && req.getScenicSpotId() != 0) {
			findReq.addWhere("scenic_spot_id", WhereEnum.EQ, req.getScenicSpotId());
		}
		if (req.getStatus() != null) {
			findReq.addWhere("status", WhereEnum.EQ, req.getStatus());
		}
		if (req.getPrintStatus() != null) {
			findReq.addWhere("print_status", WhereEnum.EQ, req.getPrintStatus());
		}
		findReq.addWhere("order_id", WhereEnum.NE, 0);
		findReq.addOrder("create_time", OrderEnum.DESC);
		findReq.setPage(req.getPageNo(), req.getPageSize());
		Page<TicketOrderDetail> ticketOrderDetailPage = page(findReq);
		return ticketOrderDetailPage;
	}

	@Override
	public Map<String, String> refundTicket(String orderDetailIdList, BmsUser bmsUser) throws Exception {
		Map<String, String> resultMap = new HashMap<>();
		Integer[] orderDetailIdArr = stringToArray(orderDetailIdList);
		for (Integer orderDetailId : orderDetailIdArr) {
			TicketOrderDetail ticketOrderDetail = get(orderDetailId);
			ticketOrderDetail.setRefundOperator(bmsUser.getId());
			TicketInfo ticketInfo = ticketInfoDao.get(ticketOrderDetail.getTicketId());
			ticketOrderDetail.setRefundTime(new Date());
			ticketOrderDetail.setRefundMoney(ticketInfo.getPrice());
			ticketOrderDetail.setStatus(UseTicketsStatusEnum.Have_a_refund.getKey());
			ticketOrderDetail.setUpdateTime(new Date());
			update(ticketOrderDetail);
		}
		resultMap.put("msg", "退票成功！");
		return resultMap;
	}

	private Integer[] stringToArray(String orderDetailIdList) {
		JSONArray array = JSONArray.parseArray(orderDetailIdList);
		LogUtils.info(array);
		Integer[] orderDetailIdArr = new Integer[array.size()];
		for (int i = 0; i < array.size(); i++) {
			Object orderDetailIdObj = array.get(i);
			Integer orderDetailId = Integer.valueOf(orderDetailIdObj.toString());
			orderDetailIdArr[i] = orderDetailId;
			LogUtils.info(orderDetailId);
		}
		LogUtils.info(orderDetailIdList);
		return orderDetailIdArr;
	}

	@Override
	public Map<String, Object> printTicket(String checkCode, Integer orderDetailId, BmsUser bmsUser) throws Exception {
		Map<String, Object> resultMap = new HashMap<>();
		TicketOrderDetail ticketOrderDetail = get(orderDetailId);
		if (ticketOrderDetail != null) {
			ticketOrderDetail.setPrintStatus(PrintStatusEnum.Already_Printed.getKey());
			ticketOrderDetail.setPrintTime(new Date());
			ticketOrderDetail.setUpdateTime(new Date());
			update(ticketOrderDetail);
			resultMap.put("msg", "打印成功！");
			return resultMap;
		}
		resultMap.put("msg", "打印失败！");
		resultMap.put("result", false);
		return resultMap;
	}

	@Override
	public Map<String, Object> refundStatistics(OrderListReqVo req, BmsUser bmsUser) throws Exception {
		Map<String, Object> resultMap = new HashMap<>();
		FindRequestEntity findReq = new FindRequestEntity();
		if (!StringUtils.isBank(req.getStartTime())) {
			findReq.addWhere("create_time", WhereEnum.GE, req.getStartTime());
		}
		if (!StringUtils.isBank(req.getEndTime())) {
			findReq.addWhere("create_time", WhereEnum.LE, req.getEndTime());
		}
		findReq.addWhere("status", WhereEnum.EQ, UseTicketsStatusEnum.Have_a_refund.getKey());
		findReq.addWhere("refund_operator", WhereEnum.EQ, bmsUser.getId());
		TicketOrder ticketOrder = ticketOrderDetailDao.refundTickStatis(findReq.getWhereList());
		resultMap.put("refundTick", ticketOrder);
		return resultMap;
	}

	@Override
	public Map<String, Object> batchQrcode(BmsUser bmsUser, Integer qrcodeNum) throws Exception {
		if (qrcodeNum > 200) {
			qrcodeNum = 200;
		}
		if (qrcodeNum > 1) {
			qrcodeNum = 1;
		}
		List<DetailQrCodeVo> detailQrCodeVoList = new ArrayList<>();
		for (int i = 0; i < qrcodeNum; i++) {
			DetailQrCodeVo detailQrCodeVo = new DetailQrCodeVo();
			TicketOrderDetail ticketOrderDetail = new TicketOrderDetail();
			String checkCode = null;
			while (true) {
				checkCode = StringUtils.generateNumbers();
				FindRequestEntity findReq = new FindRequestEntity();
				findReq.addWhere("scenic_spot_id", WhereEnum.EQ, bmsUser.getScenicSpotId());
				findReq.addWhere("check_code", WhereEnum.EQ, checkCode);
				List<TicketOrderDetail> ticketOrderDetails = ticketOrderDetailDao.find(findReq);
				if (ticketOrderDetails == null || ticketOrderDetails.size() == 0) {
					break;
				}
			}
			ticketOrderDetail.setScenicSpotId(bmsUser.getScenicSpotId());
			ticketOrderDetail.setCheckCode(checkCode);
			ticketOrderDetail.setPrintStatus(PrintStatusEnum.Already_Printed.getKey());
			ticketOrderDetail.setPrintTime(new Date());
			ticketOrderDetail.setCreateTime(new Date());
			ticketOrderDetail.setUpdateTime(new Date());
			ticketOrderDetailDao.insert(ticketOrderDetail);
			
			/*
			 * 将原二维码信息保存到数据库
			 */
			ShortQrcode shortQrcode =new ShortQrcode();
			String uuid = StringUtils.getRandomWithTimestamp16();
			shortQrcode.setUuid(uuid);
			shortQrcode.setOrderDetailId(ticketOrderDetail.getId());
			shortQrcode.setScenicSpotId(ticketOrderDetail.getScenicSpotId());
			shortQrcode.setCheckCode(ticketOrderDetail.getCheckCode());
			shortQrcodeDao.insert(shortQrcode);
			
			detailQrCodeVo.setQrCodeStr(shortQrcode.getUuid());
			detailQrCodeVo.setQrCode(QrCodeCreateUtil.generalQRCode(detailQrCodeVo.getQrCodeStr()));
			detailQrCodeVo.setCheckCode(checkCode);
			detailQrCodeVoList.add(detailQrCodeVo);
		}
		Map<String, Object> resultMap = new HashMap<>();
		resultMap.put("qrCodeList", detailQrCodeVoList);
		return resultMap;
	}

	@Override
	public Map<String, Object> inspectTicket(Integer orderId, Integer orderDetailId, String checkCode ,String appId, String IdNo)
			throws Exception {
		Map<String, Object> resultMap = new HashMap<>();
		TicketOrderDetail ticketOrderDetail = null;
		FindRequestEntity findReq = new FindRequestEntity();
		if(appId != null){
			findReq.addWhere("app_id", WhereEnum.EQ, appId);
			List<ScenicSpot> scenicSpotList = scenicSpotDao.find(findReq);
			findReq = new FindRequestEntity();
			if(scenicSpotList != null && scenicSpotList.size() >0){
				findReq.addWhere("scenic_spot_id", WhereEnum.EQ, scenicSpotList.get(0).getId());
			}else {
				resultMap.put("result", "111111");
				resultMap.put("message", "无景区信息");
				return resultMap;
			}
		}else {
			resultMap.put("result", "111111");
			resultMap.put("message", "无景区信息");
			return resultMap;
		}
		
		if (orderDetailId != null && orderDetailId != 0) {
			findReq.addWhere("id", WhereEnum.EQ, orderDetailId);
		}
		if (!StringUtils.isBank(IdNo)) {
			findReq.addWhere("user_id_bid", WhereEnum.EQ, IdNo);
		}
		if (!StringUtils.isBank(checkCode)) {
			findReq.addWhere("check_code", WhereEnum.EQ, checkCode);
		}
		findReq.addWhere("status", WhereEnum.EQ, UseTicketsStatusEnum.Already_paid.getKey());
		List<TicketOrderDetail> ticketOrderDetailList = find(findReq);
		if (ticketOrderDetailList != null && ticketOrderDetailList.size() > 0) {
			ticketOrderDetail = ticketOrderDetailList.get(0);
		}
		if (ticketOrderDetail != null) {
			if ((new Date()).before(ticketOrderDetail.getValidTime()) && ticketOrderDetail.getEntryTime().before(new Date())) {
				TicketInfo ticketInfo = ticketInfoDao.get(ticketOrderDetail.getTicketId());
				if (ticketInfo.getVerifyType() == TicketVerifyTypeEnum.One_Ticket_One_Brush.getKey()) {
					if (ticketOrderDetail.getVerifyTimes() == 0) {
						addVerifyTimes(ticketOrderDetail);
						resultMap.put("result", "000000");
						resultMap.put("message", "通过");
						return resultMap;
					}
				} else if (ticketInfo.getVerifyType() == TicketVerifyTypeEnum.More_Than_One_Ticket.getKey()) {
						if(ticketOrderDetailList != null && ticketOrderDetailList.size() > 0){
							ticketOrderDetail = ticketOrderDetailList.get(0);
							ticketOrderDetail.setVerifyTimes(ticketOrderDetail.getVerifyTimes() + 1);
							ticketOrderDetail.setLastVerifyTime(new Date());
							ticketOrderDetail.setUpdateTime(new Date());
							ticketOrderDetail.setStatus(UseTicketsStatusEnum.Already_used.getKey());
							ticketOrderDetailDao.update(ticketOrderDetail);
							addVerifyTimes(ticketOrderDetail);
							resultMap.put("result", "000000");
							resultMap.put("message", "通过");
							return resultMap;
						}else {
							resultMap.put("result", "111111");
							resultMap.put("message", "已刷完");
							return resultMap;
						}
				} else if (ticketInfo.getVerifyType() == TicketVerifyTypeEnum.Limitless_Brushc.getKey()) {
					findReq = new FindRequestEntity();
					findReq.addWhere("check_code", WhereEnum.EQ, ticketOrderDetail.getCheckCode());
					findReq.addWhere("id", WhereEnum.EQ, ticketOrderDetail.getId());
					ticketOrderDetail.setVerifyTimes(ticketOrderDetail.getVerifyTimes() + 1);
					ticketOrderDetail.setLastVerifyTime(new Date());
					ticketOrderDetail.setUpdateTime(new Date());
					ticketOrderDetailDao.update(ticketOrderDetail);
					resultMap.put("result", "000000");
					resultMap.put("message", "通过");
					return resultMap;
				}
			} else {
				resultMap.put("result", "111111");
				resultMap.put("message", "过期票");
				return resultMap;
			}
		}
		resultMap.put("result", "111111");
		resultMap.put("message", "无效票");
		return resultMap;
	}

	private void addVerifyTimes(TicketOrderDetail ticketOrderDetail) throws Exception {
		FindRequestEntity findReq = new FindRequestEntity();
		findReq.addWhere("check_code", WhereEnum.EQ, ticketOrderDetail.getCheckCode());
		findReq.addWhere("id", WhereEnum.EQ, ticketOrderDetail.getId());
		ticketOrderDetail.setVerifyTimes(ticketOrderDetail.getVerifyTimes() + 1);
		ticketOrderDetail.setLastVerifyTime(new Date());
		ticketOrderDetail.setUpdateTime(new Date());
		ticketOrderDetail.setStatus(UseTicketsStatusEnum.Already_used.getKey());
		ticketOrderDetailDao.update(ticketOrderDetail);
	}

	@Override
	public Map<String, Object> getCheckCode(String uuid, BmsUser bmsUser) throws Exception {
		Map<String, Object> resultMap = new HashMap<>();
		FindRequestEntity findReq = new FindRequestEntity();
		findReq.addWhere("uuid", WhereEnum.EQ, uuid);
		if(bmsUser != null &&  bmsUser.getScenicSpotId() != null){
			findReq.addWhere("scenic_spot_id", WhereEnum.EQ, bmsUser.getScenicSpotId());
		}
		List<ShortQrcode> shortQrcodeList = shortQrcodeDao.find(findReq);
		if(shortQrcodeList != null && shortQrcodeList.size() > 0){
			resultMap.put("shortQrcode", shortQrcodeList.get(0));
			resultMap.put("result", true);
		}
		return resultMap;
	}

}
